This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 62
Provide duck-typed PSR-14 implementation #73
Open
weierophinney
wants to merge
26
commits into
zendframework:develop
Choose a base branch
from
weierophinney:feature/psr-14-event-dispatcher-bc
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Provide duck-typed PSR-14 implementation #73
weierophinney
wants to merge
26
commits into
zendframework:develop
from
weierophinney:feature/psr-14-event-dispatcher-bc
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Since v3 still targets PHP versions prior to PHP 7.2, this patch provides a forwards-compatibility shim for the PSR-14 `StoppableEventInterface` via an additional, package-specific version that is now also implemented by default in the `Event` class.
If the method `isPropagationStopped()` is defined, use it over the `propagationIsStopped()` method.
Modifies Event::propagationIsStopped such that it now proxies to the isPropagationStopped method, and documents in the deprecation notice that this happens.
Will remove in version 4.0.
Creates a forwards-compatibility shim for the `ListenerProviderInterface`, in a new subnamespace, `Zend\EventManager\ListenerProviderInterface`.
For use in getting a lookup table of priorities and associated listeners, optionally using identifiers for lookup.
This provides the methods necessary for attaching listeners. It does not extend PrioritizedListenerProviderInterface, as we want to be able to re-use that particular interface with shared providers, which will have a different attachment mechanism in version 3 releases.
New provider implements `PrioritizedListenerAttachmentInterface` and `PrioritizedListenerProviderInterface`, and will iterate attached listeners in priority order. Each iteration will take into account both the event name, if a `getName()` method is available, the event class, and any wildcard listeners, and listeners of the same priority will be returned in the order they are attached, based on those criteria.
The PrioritizedIdentifierListenerProvider mimics functionality present in the SharedEventManager (and implements the SharedEventManagerInterface). Its purpose is to be a drop-in replacement for the `SharedEventManager` to allow users to start migrating to PSR-14 functionality. In the process of working on this implementation, I discovered some complexity in the data structure returned from `getListenersForEventByPriority` implementation of `PrioritizedListenerProvider` that, when mimiced in `PrioritizedIdentifierListenerProvider`, made verifying behavior difficult. In particular, it was this line: ```php $prioritizedListeners[$priority][] = $listOfListeners[0]; ``` The problem that arose is that the `$prioritizedListeners` returned were now two levels deep, which made comparisons far harder. I changed this to read: ``` $prioritizedListeners[$priority] = isset($prioritizedListeners[$priority]) ? array_merge($prioritizedListeners[$priority], $listOfListeners[0]) : $listOfListeners[0]; ``` This makes the return value far simpler, and _should_ keep speed reasonable, though I have yet to benchmark it.
This version acts like the combination of EventManager+SharedEventManager in terms of how it aggregates and resolves priority for listeners. The class aggregates a list of `PrioritizedListenerAttachmentInterface` instances (and implements the interface itself), looping over each in ordert to build up a prioritized list of all listeners from all providers. Since they are done in order, the order in which they should be attached generally is: - PrioritizedListenerProvider - PrioritizedIdentifierListenerProvider
…rProvider Doing so will allow us to use it in a PrioritizedAggregateListenerProvider within the EventManager later. Required a couple changes to tests, as PrioritizedIdentifierListenerProvider widens what are allowed as events and identifiers when retrieving listeners.
This is necessary to keep feature parity with current versions, but can be removed in version 4.
Added to the ListenerProvider namespace. Accepts a PrioritizedListenerAttachmentInterface argument, to which it will subscribe listeners.
Each implements ListenerSubscriberInterface::detach
Combines the features of LazyListener and LazyEventListener into `Zend\EventManager\ListenerProvider\LazyListener`. `LazyListenerSubscriber` is based on `LazyListenerAggregate`, but simplifies it by having it compose `LazyListener` instances only (no creation within it).
…PrioritizedListenerAttachmentInterface Allows the EventManager to act as its own provider.
- Adds `Zend\EventManager\EventDispatcherInterface` as a forwards compatibility shim for PSR-14. - Adds `Zend\EventManager\SharedEventManager\SharedEventManagerDecorator`, which decorates generic `SharedEventManagerInterface` instances as listener providers. - Modifies `PrioritizedAggregateListenerProvider` to accept an optional `ListenerProviderInterface $default` argument. This allows non-prioritized `SharedEventManagerInterface` instances (such as the `SharedEventManagerDecorator` in the previous item) to be fallback providers. - Modifies `Zend\EventManager\EventManager` as follows: - It now implements `EventDispatcherInterface` - It now composes a `$provider` property, and an optional `$prioritizedProvider` property. If you instantiate it per previous versions, it creates a `PrioritizedListenerProvider` instance and assigns it to the `$prioritizedProvider` property. It then checks to see if a shared manager was provided, and the type provided, to either assign the `$prioritizedProvider` as the `$provider`, or a `PrioritizedAggregateListenerProvider` that composes both the `$prioritizedProvider` and shared manager instances. - It adds a static named constructor, `createUsingListenerProvider()`, which accepts a single `ListenerProviderInterface` instance. This value is assigned to `$provider`, and, if it is a `PrioritizedListenerAttachmentInterface` instance, to the `$prioritizedProvider` property as well. - Each of the listener attachment methods (attach, detach, clearListeners, *WildcardListeners) now proxy to the composed `$prioritizedProvider`, if any. If there is none, theses methods now raise an exception. - The `getListenersForEvent()` method now proxies to the underling `$provider` property. - The `triggerListeners()` method now consumes the value of `getListenersForEvent()`. - It adds the method `dispatch($event)`, which proxies to `triggerListeners()`, and returns the `$event` it was passed. The method raises an exception of `$event` is a non-object. - Each of `trigger()`, `triggerUntil`, `triggerEvent`, `triggerEventUntil`, `getIdentifiers`, `setIdentifiers`, `addIdenitifers`, `getSharedManager`, `attach`, `detach`, `attachWildcardListener`, `detachWildcardListener`, `clearListeners`, and `getListenersForEvent` have been marked deprecated. - Updates `EventListenerIntrospectionTrait` to work with the new internals of the `EventManager`. - Updates `EventManagerTest`: - updates `getListenersForEvent()` to work with the new `EventManager` internals - Removes `testAttachShouldAddEventIfItDoesNotExist` as it was irrelevant even before the changes. - Removes the `testTriggeringAnEventWithAnEmptyNameRaisesAnException` test, as this is no longer true; you can use any object as an event now. - Modifies a few tests where they were accessing internal structures that have changed, while keeping the same assertions in place. - Adds `EventManagerWithProviderTest` to demonstrate usage when creating an `EventManager` via its `createUsingListenerProvider()` method. - Updates `EventListenerIntrospectionTraitTest` to work with the new internals of the `EventManager`.
Basically, a counterpart to the current EventManagerAwareInterface, but for EventDispatcherInterface composition. Also revises the Deprecations list, as we can keep EventManager as an EventDispatcherInterface implementation for 4.0.
- `EventInterface` - `EventManagerInterface` - `EventManagerAwareInterface` - `EventManagerAwareTrait` - `EventsCapableInterface` (points people to `EventDispatchingInterface`) - `SharedEventManager` - `SharedEventManagerInterface` - `SharedEventsCapableInterface` - `ListenerAggregateInterface` (points people to the `PrioritizedListenerAttachmentInterface`) - `ListenerAggregateTrait` (points people to `ListenerSubscriberTrait`) - `AbstractListenerAggregate` (points people to `AbstractListenerSubscriber` and/or `ListenerSubscriberTrait`) - `ResponseCollection` (tells people to aggregate state/results in the event itself) - `LazyListener` (points people to `ListenerProvider\LazyListener`) - `LazyEventListener` (points people to `ListenerProvider\LazyListener`) - `LazyListenerAggregate` (points people to `ListenerProvider\LazyListenerSubscriber`) - `FilterChain` and `Filter` subnamespace (this should be done in a separate component)
We now require ^1.2 to ensure that PSR-11 interfaces are also present, allowing new classes to typehint only on the PSR-11 interfaces. This will allow compatibility to continue as the 1.2 variants extend the PSR-11 interfaces.
Previously, `assertInternalType('iterable')`, which only works on PHP 7.1+.
Required to allow us to test against PHP 5.6.
whitespace and long lines
weierophinney
force-pushed
the
feature/psr-14-event-dispatcher-bc
branch
from
April 10, 2019 14:45
1e8c205
to
c367037
Compare
Notes all new features, major changes, and deprecations.
`yield from` was introduced in PHP 7. As such, to work in PHP 5.6, we need to modify the statements to iterate over the inner generator and yield results directly.
weierophinney
force-pushed
the
feature/psr-14-event-dispatcher-bc
branch
from
April 10, 2019 15:56
e9c15b4
to
357d508
Compare
3 tasks
This repository has been closed and moved to laminas/laminas-eventmanager; a new issue has been opened at laminas/laminas-eventmanager#2. |
This repository has been moved to laminas/laminas-eventmanager. If you feel that this patch is still relevant, please re-open against that repository, and reference this issue. To re-open, we suggest the following workflow:
|
3 tasks
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch provides a forwards-compatibility release that adapts zend-eventmanager to work as a PSR-14 EventDispatcher. It does so by doing the following:
ListenerProviderInterface
andEventDispatcherInterface
versions that work with PHP 5.6.ListenerProvider
subnamespace; this includes both the listener attachment previously in theEventManager
instance as well as theSharedEventManager
instance.ListenerProvider
subnamespace.EventManager
to consume listener providers. By default, it will create a default priority-based listener provider, and have its various listener attachment methods proxy to that provider; it then aggregates that provider with the SharedEventManager (which is itself a provider now) in order to retrieve listeners. This is done in such a way that behavior is completely backwards compatible with current usage.createUsingListenerProvider()
, allows providing a specific listener provider for use with theEventManager
. If the provider is attachment capable, the various listener attachment methods will proxy to it; otherwise, they will raise an exception.The patch also deprecates a number of features, including:
EventInterface
.TODO